﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using YArchitech.Revit;
using YJKArch.Utils;
using RegionSplittor.Utils;

namespace RegionSplittor.Data
{
	public class BeamCellData
	{
		public CurveArray GetCurveArray()
		{
			CurveArray curveArray = new CurveArray();
			foreach (CurveElementData curveElementData in this.m_arCurve)
			{
				curveArray.Append(curveElementData.m_Curve);
			}
			return curveArray;
		}

		public CurveLoop GetCurveLoop()
		{
			CurveLoop curveLoop = new CurveLoop();
			try
			{
				foreach (CurveElementData curveElementData in this.m_arCurve)
				{
					curveLoop.Append(curveElementData.m_Curve);
				}
			}
			catch
			{
				try
				{
					List<XYZ> list = new List<XYZ>();
					foreach (CurveElementData curveElementData2 in this.m_arCurve)
					{
						Curve curve = curveElementData2.m_Curve;
						XYZ hyendPoint = curve.GetEndPoint(0);
						XYZ hyendPoint2 = curve.GetEndPoint(1);
						list.Add(hyendPoint);
						list.Add(hyendPoint2);
					}
					List<XYZ> list2 = ConvexHull.Convert2ConvexHull(list);
					if (list2.Count > 2)
					{
						List<Curve> list3 = new List<Curve>();
						int count = list2.Count;
						for (int i = 0; i < list2.Count; i++)
						{
							XYZ xyz;
							XYZ xyz2;
							if (i == count - 1)
							{
								xyz = list2[count - 1];
								xyz2 = list2[0];
							}
							else
							{
								xyz = list2[i];
								xyz2 = list2[i + 1];
							}
							Curve curve2 = Line.CreateBound(xyz, xyz2);
							if (null != curve2)
							{
								list3.Add(curve2);
							}
						}
						if (list3.Count > 2)
						{
							curveLoop = CurveLoop.Create(list3);
						}
					}
				}
				catch
				{
				}
			}
			return curveLoop;
		}

		public CurveLoop GetSecondaryCurveLoop(Autodesk.Revit.DB.Document doc)
		{
			CurveLoop result = null;
			try
			{
				double beamLocationZValue = this.GetBeamLocationZValue(doc);
				List<XYZ> list = new List<XYZ>();
				foreach (CurveElementData curveElementData in this.m_arCurve)
				{
					Curve curve = curveElementData.m_Curve;
					XYZ hyendPoint = curve.GetEndPoint(0);
					XYZ hyendPoint2 = curve.GetEndPoint(1);
					list.Add(hyendPoint);
					list.Add(hyendPoint2);
				}
				List<XYZ> list2 = ConvexHull.Convert2ConvexHull(list);
				if (list2.Count > 2)
				{
					List<Curve> list3 = new List<Curve>();
					int count = list2.Count;
					for (int i = 0; i < count; i++)
					{
						XYZ xyz;
						XYZ xyz2;
						if (i == count - 1)
						{
							xyz = list2[count - 1];
							xyz2 = list2[0];
						}
						else
						{
							xyz = list2[i];
							xyz2 = list2[i + 1];
						}
						Curve curve2 = null;
						if (xyz != null && xyz2 != null)
						{
							curve2 = Line.CreateBound(xyz, xyz2);
						}
						if (null != curve2)
						{
							double z = xyz.Z;
							Transform transform = Transform.CreateTranslation(new XYZ(0.0, 0.0, beamLocationZValue - z));
							list3.Add(curve2.CreateTransformed(transform));
						}
					}
					if (list3.Count > 2)
					{
						result = CurveLoop.Create(list3);
					}
				}
			}
			catch
			{
			}
			return result;
		}

		public CurveLoop GetFloorCurveLoop(Autodesk.Revit.DB.Document doc)
		{
			CurveLoop secondaryCurveLoop = this.GetSecondaryCurveLoop(doc);
			if (secondaryCurveLoop == null)
			{
				return null;
			}
			double primaryBeamHeight = this.GetPrimaryBeamHeight(doc);
			Transform transform = Transform.CreateTranslation(new XYZ(0.0, 0.0, -primaryBeamHeight));
			List<Curve> list = new List<Curve>();
			CurveLoopIterator curveLoopIterator = secondaryCurveLoop.GetCurveLoopIterator();
			while (curveLoopIterator.MoveNext())
			{
				Curve curve = curveLoopIterator.Current;
				list.Add(curve.CreateTransformed(transform));
			}
			return CurveLoop.Create(list);
		}

		public List<ElementId> GetBeamIdsByType(BeamOrderType type)
		{
			List<ElementId> list = new List<ElementId>();
			foreach (CurveElementData curveElementData in this.m_arCurve)
			{
				if (curveElementData.m_BeamType == type)
				{
					list.Add(curveElementData.m_ElementId);
				}
			}
			return list.Distinct<ElementId>().ToList<ElementId>();
		}

		public double GetBeamHeightByType(BeamOrderType type)
		{
			double result = 0.0;
			foreach (CurveElementData curveElementData in this.m_arCurve)
			{
				if (curveElementData.m_BeamType == type)
				{
					result = curveElementData.m_dBeamHeight;
					break;
				}
			}
			return result;
		}

		public List<CurveElementData> GetBeamCurveData(BeamOrderType type)
		{
			List<CurveElementData> list = new List<CurveElementData>();
			foreach (CurveElementData curveElementData in this.m_arCurve)
			{
				if (curveElementData.m_BeamType == type)
				{
					list.Add(curveElementData);
				}
			}
			return list;
		}

		public double GetBeamHeightById(ElementId id)
		{
			double result = 0.0;
			foreach (CurveElementData curveElementData in this.m_arCurve)
			{
				if (curveElementData.m_ElementId == id)
				{
					result = curveElementData.m_dBeamHeight;
					break;
				}
			}
			return result;
		}

		public double GetBeamLocationZValue(Autodesk.Revit.DB.Document doc)
		{
			double result = 0.0;
			foreach (CurveElementData curveElementData in this.m_arCurve)
			{
				if (curveElementData.m_BeamType == BeamOrderType.BT_PrimaryBeam)
				{
					FamilyInstance familyInstance = doc.GetElement(curveElementData.m_ElementId) as FamilyInstance;
					if (familyInstance != null)
					{
						LocationCurve locationCurve = familyInstance.Location as LocationCurve;
						if (locationCurve != null)
						{
							result = locationCurve.Curve.GetEndPoint(0).Z;
							break;
						}
					}
				}
			}
			return result;
		}

		public double GetPrimaryBeamHeight(Autodesk.Revit.DB.Document doc)
		{
			double result = 0.0;
			bool flag = false;
			foreach (CurveElementData curveElementData in this.m_arCurve)
			{
				if (curveElementData.m_BeamType == BeamOrderType.BT_PrimaryBeam)
				{
					FamilyInstance familyInstance = doc.GetElement(curveElementData.m_ElementId) as FamilyInstance;
					if (familyInstance != null)
					{
						result = BeamOperator.GetBeamHeight(familyInstance);
						flag = true;
						break;
					}
				}
			}
			if (!flag)
			{
				result = Common.MMtoIntch(700.0);
			}
			return result;
		}

		public Curve GetCellCurveById(ElementId id)
		{
			Curve result = null;
			foreach (CurveElementData curveElementData in this.m_arCurve)
			{
				if (curveElementData.m_ElementId.IntegerValue == id.IntegerValue)
				{
					result = curveElementData.m_Curve;
					break;
				}
			}
			return result;
		}

		public List<Curve> GetCellCurveById(List<ElementId> arId)
		{
			List<Curve> list = new List<Curve>();
			foreach (ElementId id in arId)
			{
				Curve cellCurveById = this.GetCellCurveById(id);
				if (null != cellCurveById)
				{
					list.Add(cellCurveById);
				}
			}
			return list;
		}

		public List<CurveElementData> m_arCurve = new List<CurveElementData>();

		public RegionBeamCellType m_BeamCellType;

		public double m_CellArea;

		public XYZ m_ptCenter;

		public double m_dFloorHeight;
	}
}
